package com.dirox.confluence.labelmanagement.action;

import com.atlassian.confluence.core.Beanable;
import com.atlassian.confluence.core.ConfluenceActionSupport;
import com.atlassian.confluence.core.service.ValidationError;
import com.atlassian.confluence.labels.LabelManager;
import com.atlassian.confluence.spaces.SpaceManager;
import com.atlassian.confluence.util.ajax.AjaxResponse;

import com.dirox.confluence.labelmanagement.service.LabelManagementService;
import static com.google.common.base.Preconditions.checkNotNull;

import org.apache.commons.lang.StringUtils;

import org.apache.log4j.Logger;

/**
 * MergeLabelAjaxAction extends ConfluenceActionSupport implements Beanable
 * <p>
 * This class implement merge label action.
 *
 */
public class MergeLabelAjaxAction extends ConfluenceActionSupport
    implements Beanable {
    private static final long serialVersionUID = 1L;
    private static Logger log = Logger.getLogger(MergeLabelAjaxAction.class);
    private SpaceManager spaceManager;
    private LabelManagementService labelManagementService;
    private Object bean;
    private String secondLabel;
    private String firstLabel;
    private String spaceKey;
    private LabelManager labelManager;

    /**
     * This method executes the merge label action
     * @return the result of action in String (ERROR|SUCCESS)
     * @throws Exception
     */
    public String mergeLabel() throws Exception {
        // Validate input values
        if (!validateInput()) {
            return ERROR;
        }

        try {
            // Check if spaceKey is not blank then merge in this space,
            // else merge in all spaces.
            if (StringUtils.isNotBlank(spaceKey)) {
                labelManagementService.mergeLabelInSpace(spaceKey, firstLabel,
                    secondLabel);
            } else {
                labelManagementService.mergeLabelInAllSpaces(firstLabel,
                    secondLabel);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e.getCause());
            bean = AjaxResponse.failure(getText(e.getMessage()));

            return ERROR;
        }

        bean = AjaxResponse.success(getText("label-management.code.success"));

        return SUCCESS;
    }

    /**
     * Method for validating input for merge label action.
     * <p>
     * - First, validate if labels are empty, return false.<br/>
     * - Second, validate if two labels are the same, return false.<br/>
     * - Third, validate if labels do not exist, return false.<br/>
     * - Final, validate if space does not exist (when space is specified)
     * @return boolean
     */
    private boolean validateInput() {
        // check if the labels are empty
        if (StringUtils.isBlank(firstLabel) ||
                StringUtils.isBlank(secondLabel)) {
            bean = AjaxResponse.failure(getText(
                        "label-management.error.empty.label"));

            return false;
        }

        // check if the new label contains "space" character
        if (secondLabel.contains(" ")) {
            bean = AjaxResponse.failure(getText(
                        "label-management.error.space.character"));

            return false;
        }

        // check if the labels are the same
        if (secondLabel.equalsIgnoreCase(firstLabel)) {
            bean = AjaxResponse.failure(getText(
                        "label-management.merge.error.duplicate.label"));

            return false;
        }

        // validate label
        ValidationError error = labelManagementService.getLabelValidationError(secondLabel);

        if (error != null) {
            bean = AjaxResponse.failure(getText(
                        "label-management.error.invalid.character"));

            return false;
        }

        // check if the labels do not exist
        if ((labelManager.getLabel(firstLabel) == null) ||
                (labelManager.getLabel(secondLabel) == null)) {
            bean = AjaxResponse.failure(getText(
                        "label-management.error.not.exist.label"));

            return false;
        }

        // check if the space does not exist
        if (StringUtils.isNotBlank(spaceKey) &&
                (spaceManager.getSpace(spaceKey) == null)) {
            bean = AjaxResponse.failure(getText(
                        "label-management.error.not.exist.space"));

            return false;
        }

        return true;
    }

    @Override
    public Object getBean() {
        return bean;
    }

    public String getSecondLabel() {
        return secondLabel;
    }

    public void setSecondLabel(String secondLabel) {
        this.secondLabel = secondLabel;
    }

    public String getFirstLabel() {
        return firstLabel;
    }

    public void setFirstLabel(String firstLabel) {
        this.firstLabel = firstLabel;
    }

    public String getSpaceKey() {
        return spaceKey;
    }

    public void setSpaceKey(String spaceKey) {
        this.spaceKey = spaceKey;
    }

    public void setSpaceManager(SpaceManager spaceManager) {
        this.spaceManager = checkNotNull(spaceManager);
    }

    public void setLabelManagementService(
        LabelManagementService labelManagementService) {
        this.labelManagementService = checkNotNull(labelManagementService);
    }

    public void setLabelManager(LabelManager labelManager) {
        this.labelManager = checkNotNull(labelManager);
    }
}
